/**
 * 
 */
package com.terrence.filemgr.mgr.impl.localfs;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;

import com.terrence.filemgr.FileMgrException;
import com.terrence.filemgr.mgr.AbsFileMgr;
import com.terrence.filemgr.mgr.AbsFileMgrContext;
import com.terrence.filemgr.mgr.FilePathGenerator;
import com.terrence.filemgr.mgr.vo.DirVo;

/**
 * @author wuchuang
 *
 * 2016年10月28日 下午5:31:57
 * 
 * 本地文件系统实现
 */
public class LocalFSMgr extends AbsFileMgr {
	private LocalFSContext context = null;
	
	public LocalFSMgr(AbsFileMgrContext context) {
		super(context);
		this.context = (LocalFSContext)context;
	}
	
	@Override
	public String upload(InputStream is, String fileRelativeDir,String fileName) throws FileMgrException {
		OutputStream os = null;
		try {
			fileRelativeDir = (null == fileRelativeDir ? "":fileRelativeDir);
			
			File dir = new File(context.getBaseDir()+context.getPathSeperator()+fileRelativeDir);
			if(!dir.exists() && !dir.isDirectory()){
				dir.mkdirs();
			}
			File file = new File(context.getBaseDir()+context.getPathSeperator()+fileRelativeDir+context.getPathSeperator()+fileName);
			os = new FileOutputStream(file);
			byte buffer[]=new byte[1024];
			int len = 0;
			while((len = is.read(buffer)) != -1){ 
				os.write(buffer,0,len);
			}
			return fileRelativeDir+context.getPathSeperator()+fileName;
		} catch (Exception e) {
			throw new FileMgrException(e);
		} finally{
			if(null!=os){
				try{
					os.flush();
		            os.close();
				}catch(Exception ex){
					//异常不处理
				}
			}
		}
	}

	@Override
	public String upload(InputStream is,String fileType) throws FileMgrException {
		OutputStream os = null;
		try {
			String fileDir = FilePathGenerator.generateDirPath(context.getPathSeperator(), context.getBaseDir());
			String fileName = FilePathGenerator.generateFileName(fileType);
			File dir = new File(fileDir);
			if(!dir.exists() && !dir.isDirectory()){
				dir.mkdirs();
			}
			File file = new File(fileDir+fileName);
			os = new FileOutputStream(file);
			byte buffer[]=new byte[1024];
			int len = 0;
			while((len = is.read(buffer)) != -1){ 
				os.write(buffer,0,len);
			}
			return fileDir+fileName;
		} catch (Exception e) {
			throw new FileMgrException(e);
		} finally{
			if(null!=os){
				try{
					os.flush();
		            os.close();
				}catch(Exception ex){
					//异常不处理
				}
			}
		}
	}

	@Override
	public InputStream download(String fileRelativePath) throws FileMgrException {
		try {
			InputStream fis = new BufferedInputStream(new FileInputStream(context.getBaseDir()+context.getPathSeperator()+fileRelativePath));
			return fis;
		} catch (Exception e) {
			throw new FileMgrException(e);
		}
	}

	@Override
	public Boolean remove(String fileRelativePath) throws FileMgrException {
		Boolean isFinished = Boolean.TRUE;
		File file = new File(context.getBaseDir()+context.getPathSeperator()+fileRelativePath);
		if (file.exists() && file.isFile()) {
			isFinished = isFinished && file.delete();
		}
		return isFinished;
	}

	@Override
	public void createDir(String relativePath,String dirName) throws FileMgrException {
		try {
			relativePath = (null == relativePath ? "":relativePath);
			dirName = (null == dirName ? "" : dirName);
			File dir = new File(context.getBaseDir()+context.getPathSeperator()+relativePath+context.getPathSeperator()+dirName);
			if(!dir.exists() && !dir.isDirectory()){
				dir.mkdirs();
			}
		} catch (Exception e) {
			throw new FileMgrException(e);
		}
	}
	
	@Override
	public Boolean isDirValid(String dirPath) throws FileMgrException{
		try {
			dirPath = (null == dirPath ? "" : dirPath);
			//将测试文件上传到指定目录
			String filePath = upload(LocalFSMgr.class.getResourceAsStream("../check.file"), dirPath, "check.file");
			//删除测试文件
			remove(context.getBaseDir()+context.getPathSeperator()+filePath);
			return Boolean.TRUE;
		} catch (Exception e) {
			return Boolean.FALSE;
		}
	}
	
	@Override
	public DirVo getDirStructures(String relativePath) throws FileMgrException {
		try {
			relativePath = (null == relativePath ? "":relativePath);
			File dir = new File(context.getBaseDir()+context.getPathSeperator()+relativePath);
			return readDirstructures(dir, null);
		} catch (Exception e) {
			throw new FileMgrException(e);
		}
	}
	
	/**
	 * 
	 * 获取目录结构
	 * @param dir
	 * @param parentDir
	 * @return
	 * @throws FileMgrException
	 */
	private DirVo readDirstructures(File dir,DirVo parentDir) throws FileMgrException {
		try {
			DirVo dirVo = null;
			if(dir.exists() && dir.isDirectory()){
				dirVo = new DirVo();
				dirVo.setName(dir.getName());
				if(null != parentDir){
					dirVo.setPath(parentDir.getPath() + context.getPathSeperator() + dir.getName());
					parentDir.addSubDir(dirVo);
				}else{
					dirVo.setPath("");
				}
				
				File[] subDirs = dir.listFiles();
				for(File subDir : subDirs){
					readDirstructures(subDir, dirVo);
				}
			}
			return dirVo;
		} catch (Exception e) {
			throw new FileMgrException(e);
		}
	}
	
}
